package io.geekidea.boot.jab.service.impl;

import cn.hutool.json.JSONString;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import io.geekidea.boot.common.constant.JieAnBoAPiConstant;
import io.geekidea.boot.jab.dto.AiDto;
import io.geekidea.boot.jab.dto.PushMessageDto;
import io.geekidea.boot.jab.dto.QueryParkChannelDto;
import io.geekidea.boot.jab.service.JieAnBoApiService;
import io.geekidea.boot.util.api.JieAnBoApi;
import io.geekidea.boot.webStock.handler.WebSocketHandler;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import io.geekidea.boot.jieanbo.dto.AiSetDto;
import io.geekidea.boot.jieanbo.service.AiSetService;
import io.geekidea.boot.jieanbo.vo.AiSetVo;

@Service
public class JieAnBoApiServiceImpl implements JieAnBoApiService {


    private StringBuilder sentenceBuffer = new StringBuilder();
    private static final String[] SENTENCE_ENDINGS = {"。", "！", "？", ".", "!", "?", "\n"};

    private final RedisTemplate<String, Object> redisTemplate;
    private final AiSetService aiSetService;

    public JieAnBoApiServiceImpl(RedisTemplate<String, Object> redisTemplate, AiSetService aiSetService) {
        this.redisTemplate = redisTemplate;
        this.aiSetService = aiSetService;
    }

    @Override
    public Object queryParkChannel(QueryParkChannelDto dto) {
        String url = JieAnBoAPiConstant.APP_URL + dto.getUrl();
        JsonNode body = dto.getBody();

        JSONObject response = JieAnBoApi.postForJson(url, JSONObject.toJSONString(body));
        return response;
    }

    @Override
    public void pushMessage(PushMessageDto dto) {
        System.out.println("Received push message: " + dto);
    }

    @Override
    public ResponseBodyEmitter ai(AiDto dto) {
        SseEmitter emitter = new SseEmitter(-1L); // 设置无限超时
        
        // Start a new thread to handle the streaming response
        new Thread(() -> {
            try {
                // 从Redis获取AI配置
                String redisKey = "jieanboAi";
                AiSetDto aiConfig = (AiSetDto) redisTemplate.opsForValue().get(redisKey);
                
                // 如果Redis中没有配置，则从数据库获取并存入Redis
                if (aiConfig == null) {
                    AiSetVo aiSetVo = aiSetService.getOneAiSet();
                    if (aiSetVo != null) {
                        aiConfig = new AiSetDto();
                        BeanUtils.copyProperties(aiSetVo, aiConfig);
                        // 存入Redis
                        redisTemplate.opsForValue().set(redisKey, aiConfig);
                    }
                }


//                String apiUrl = "https://api.htzl.com.cn:30000/v1/chat/completions";
//                String authorization = "Bearer sk-lcAXPRIsvzJpDYb_E-Bmb28C__dcGFgqg02dCQuqTn4C3vKS_-YGau68g2A";
//                String model = "Pro/deepseek-ai/DeepSeek-V3";
//                String prompt = "作为一个停车场的智能管家，不是停车相关问题不回答，问题:";
                String apiUrl = aiConfig.getApiurl();
                String authorization = aiConfig.getAuthorization();;
                String model = aiConfig.getModel();;
                String prompt = aiConfig.getPrompt();;
                String content = "";

                //未后端传入做判断用
                if ("admin".equals(dto.getType())) {
                    content = dto.getProblem();
                }else {
                    content = prompt + dto.getProblem();
                }

                // Create connection
                URL url = new URL(apiUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                
                // Set request headers
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", authorization);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setRequestProperty("Accept", "text/event-stream");
                connection.setRequestProperty("Cache-Control", "no-cache");
                connection.setDoOutput(true);
                
                // Build request JSON
                String jsonPayload = buildRequestJson(model, content);
                
                // Write request body
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonPayload.getBytes(StandardCharsets.UTF_8);
                    os.write(input, 0, input.length);
                    os.flush();
                }
                
                // Get response
                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("Error: HTTP " + responseCode));
                    emitter.complete();
                    return;
                }
                
                // Read streaming response
                List<String> eventBuffer = new ArrayList<>();
                
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        if (line.isEmpty()) {
                            processAndSendEvent(eventBuffer, emitter);
                            eventBuffer.clear();
                        } else {
                            eventBuffer.add(line);
                        }
                    }
                }
                
                // Process any remaining events
                if (!eventBuffer.isEmpty()) {
                    processAndSendEvent(eventBuffer, emitter);
                }
                
                // 发送完成事件
                emitter.send(SseEmitter.event()
                        .name("complete")
                        .data(""));
                emitter.complete();
                
            } catch (Exception e) {
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("Error: " + e.getMessage()));
                    emitter.complete();
                } catch (IOException ex) {
                    emitter.completeWithError(ex);
                }
            }
        }).start();
        
        return emitter;
    }
    
    private String buildRequestJson(String model, String content) {
        StringBuilder json = new StringBuilder();
        json.append("{");
        json.append("\"model\": \"").append(escapeJson(model)).append("\",");
        json.append("\"messages\": [{");
        json.append("\"role\": \"user\",");
        json.append("\"content\": \"").append(escapeJson(content)).append("\"");
        json.append("}],");
        json.append("\"stream\": true,");
        json.append("\"max_tokens\": 4096,");
        json.append("\"temperature\": 0.7");
        json.append("}");
        return json.toString();
    }
    
    private String escapeJson(String value) {
        return value.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("/", "\\/")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }
    
    private void processAndSendEvent(List<String> eventLines, SseEmitter emitter) throws IOException {
        StringBuilder data = new StringBuilder();
        for (String eventLine : eventLines) {
            if (eventLine.startsWith("data:")) {
                String payload = eventLine.substring(5).trim();
                data.append(payload);
            }
        }
        
        if ("[DONE]".equals(data.toString())) {
            // 发送剩余的缓冲区内容
            if (sentenceBuffer.length() > 0) {
                emitter.send(SseEmitter.event()
                        .name("message")
                        .data(sentenceBuffer.toString()));
                sentenceBuffer.setLength(0);
            }
            return;
        }
        
        if (data.indexOf("\"content\":") > 0) {
            int start = data.indexOf("\"content\":\"") + 11;
            int end = data.indexOf("\"", start);
            if (start > 10 && end > start) {
                String content = data.substring(start, end);
                String unescapedContent = unescapeJson(content);
                
                // 将新内容添加到句子缓冲区
                sentenceBuffer.append(unescapedContent);
                
                // 检查是否形成完整句子
                String currentText = sentenceBuffer.toString();
                for (String ending : SENTENCE_ENDINGS) {
                    if (currentText.contains(ending)) {
                        // 找到最后一个完整句子的位置
                        int lastSentenceEnd = 0;
                        for (String endMark : SENTENCE_ENDINGS) {
                            int pos = currentText.lastIndexOf(endMark);
                            if (pos > lastSentenceEnd) {
                                lastSentenceEnd = pos + 1;
                            }
                        }
                        
                        if (lastSentenceEnd > 0) {
                            // 发送完整句子
                            String completeSentence = currentText.substring(0, lastSentenceEnd);
                            emitter.send(SseEmitter.event()
                                    .name("message")
                                    .data(completeSentence));
                            
                            // 保留未完成的句子
                            sentenceBuffer = new StringBuilder(currentText.substring(lastSentenceEnd));
                        }
                        break;
                    }
                }
            }
        }
    }
    
    private String unescapeJson(String value) {
        return value.replace("\\n", "\n")
                .replace("\\r", "\r")
                .replace("\\t", "\t")
                .replace("\\\"", "\"")
                .replace("\\\\", "\\");
    }
}
